#ifndef XSHAREDPTR_H
#define XSHAREDPTR_H

#include <QDebug>

class Counter
{
public:
    Counter() : s(0), w(0) {}

    int s; //startptr引用计数
    int w; //weakptr引用计数
};

template <class T>
class XSharedPtr
{
public:
    XSharedPtr(T *p = 0) : m_ptr(p)
    {
        m_count = new Counter();
        if (p) {
            m_count->s = 1;
        }
        qDebug() << "[default construct] m_ptr:" << m_ptr << "count:" << m_count->s;
    }

    XSharedPtr(XSharedPtr<T> const &s)
    {
        s.m_count->s++;
        m_ptr = s.m_ptr;
        m_count = s.m_count;
        qDebug() << "[copy construct] m_ptr:" << m_ptr << "count:" << m_count->s;
    }

    XSharedPtr<T> &operator=(XSharedPtr<T> &s)
    {
        if (this != &s) {
            release();
            s.m_count->s++;
            m_ptr = s.m_ptr;
            m_count = s.m_count;
            qDebug() << "[= construct] m_ptr:" << m_ptr << "count:" << m_count->s;
        }
        return *this;
    }

    ~XSharedPtr()
    {
        release();
    }

    T *operator->()
    {
        return m_ptr;
    }

    T &operator*()
    {
        return *m_ptr;
    }

protected:
    void release()
    {
        if (m_count->s <= 0)
            return;

        m_count->s--;
        if (m_count->s < 1)
        {
            delete m_ptr;
            m_ptr = nullptr;
        }
        qDebug() << "[release] m_ptr:" << m_ptr << "count:" << m_count->s;
    }

private:
    T *m_ptr;
    Counter *m_count;
};

#endif // XSHAREDPTR_H
